package com.dreamoo.interceptor;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.dreamoo.common.Constant;
import com.dreamoo.common.pojo.info.UserLoginInfo;
import com.dreamoo.common.util.TokenUtil;
import com.dreamoo.common.threadlocal.BaseParameterHolder;
import com.dreamoo.common.threadlocal.ThreadLocalConstant;
import com.dreamoo.redis.RedisCacheUtil;
import com.dreamoo.redis.constant.RedisConstant;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author 山顶洞人郑某
 * @className LoginInterceptor.java 用户登录拦截器
 * @date 2025 05 07
 */
@AllArgsConstructor
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    private final RedisCacheUtil redisCacheUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        log.info("请求开始：{}", request.getRequestURI());
       //先获取请求头中的token
        String token = request.getHeader(Constant.TOKEN);
        if (StrUtil.isEmpty(token)) {
            //请求头中没有Token
            log.info("请求头中没有Token");
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.getWriter().write("Access Forbidden");
            return false;
        }
        //获取到Token并解析Token
        String tokenParm = TokenUtil.parseToken(token, Constant.TOKEN_SECRET);
        //利用Token 从Redis中获取到用户信息
        String userId = String.valueOf(JSONObject.parseObject(tokenParm).get(Constant.USER_ID));
        if (StrUtil.isEmpty(userId)) {
            //用户不存在
            log.info("用户不存在");
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.getWriter().write("Access Forbidden");
            return false;
        }
        //从redis中获取用户信息
        UserLoginInfo userLoginInfo = redisCacheUtil.opsForValue(RedisConstant.USER_LOGIN_INFO + userId,Constant.TOKEN_EXPIRE_TIME, TimeUnit.SECONDS, UserLoginInfo.class);
        if (Objects.isNull(userLoginInfo)) {
            log.info("用户不存在");
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.getWriter().write("Access Forbidden");
            return false;
        }
        //存储用户信息到线程局部
        BaseParameterHolder.set(ThreadLocalConstant.USER_LOGIN_INFO, userLoginInfo);
        return true;
    }


    /**
     * 请求完成后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        BaseParameterHolder.remove();
    }

}
